/*
*****************************************************************
* Copyright All Reserved © 2015-2025 Solonix-Chu
*****************************************************************
*/

#ifndef __UORB_NODE_H__
#define __UORB_NODE_H__

#include "uORB.h"
// #include "uorb_utils.h"
#include <rtthread.h>

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#ifndef ORB_MULTI_MAX_INSTANCES
#define ORB_MULTI_MAX_INSTANCES 4
#endif //ORB_MULTI_MAX_INSTANCES

/**
 * Generates a pointer to the uORB metadata structure for
 * a given topic.
 *
 * The topic must have been declared previously in scope
 * with ORB_DECLARE().
 *
 * @param _name		The name of the topic.
 */
#define ORB_ID(_name) &__orb_##_name

/**
 * Declare (prototype) the uORB metadata for a topic (used by code generators).
 *
 * @param _name		The name of the topic.
 */
#define ORB_DECLARE(_name) extern const struct orb_metadata_s __orb_##_name __EXPORT

/**
 * Define (instantiate) the uORB metadata for a topic.
 *
 * The uORB metadata is used to help ensure that updates and
 * copies are accessing the right data.
 *
 * Note that there must be no more than one instance of this macro
 * for each topic.
 *
 * @param _name		The name of the topic.
 * @param _struct	The structure the topic provides.
 * @param _size_no_padding	Struct size w/o padding at the end
 * @param _fields	All fields in a semicolon separated list e.g: "float[3] position;bool armed"
 * @param _orb_id_enum	ORB ID enum e.g.: ORB_ID::vehicle_status
 */
#define ORB_DEFINE(_name, _struct, _size_no_padding, _fields, _orb_id_enum) \
    const struct orb_metadata_s __orb_##_name = {                           \
        #_name,                                                             \
        sizeof(_struct),                                                    \
        _size_no_padding,                                                   \
        _fields,                                                            \
        _orb_id_enum,                                                       \
    };

/**
 * Object metadata.
 */
typedef struct orb_metadata_s
{
    const char    *o_name;            /**< unique object name */
    const uint16_t o_size;            /**< object size */
    const uint16_t o_size_no_padding; /**< object size w/o padding at the end (for logger) */
    const char    *o_fields;          /**< semicolon separated list of fields (with type) */
    uint8_t        o_id;              /**< ORB_ID enum */
} orb_metadata_t;

typedef const struct orb_metadata_s *orb_id_t;


typedef struct orb_callback_s
{
    rt_list_t list;
    void (*call)();
} orb_callback_t;

typedef struct orb_node_s
{
    rt_list_t                    list;
    const struct orb_metadata_s *meta;
    rt_uint8_t                   instance;         // 实例序号
    rt_uint8_t                   queue_size;       // 栈的长度
    rt_uint32_t                  generation;       // 更新代数
    rt_list_t                    callbacks;        // 回调函数链表
    rt_bool_t                    advertised;       // 是否公告
    rt_uint8_t                   subscriber_count; // 订阅者个数
    rt_bool_t                    data_valid;       // data是否有效
    rt_uint8_t                  *data;
    rt_uint32_t                  dev_min_interval;
    rt_tick_t                    last_read_timestamp;
    uorb_notifier_t              notifier;       // 事件通知器（用于阻塞等待）
    rt_bool_t                    pending_delete; // 延迟删除标记
} orb_node_t;

/**
 * ORB topic advertiser handle.
 *
 * Advertiser handles are global; once obtained they can be shared freely
 * and do not need to be closed or released.
 *
 * This permits publication from interrupt context and other contexts where
 * a file-descriptor-based handle would not otherwise be in scope for the
 * publisher.
 */
typedef orb_node_t *orb_advert_t;


typedef struct orb_subscribe_s
{
    const struct orb_metadata_s *meta;
    rt_uint8_t                   instance;
    rt_tick_t                    interval;
    orb_node_t                  *node;
    rt_uint32_t                  generation;
    rt_tick_t                    last_update_timestamp;
    rt_bool_t                    callback_registered;
} orb_subscribe_t;


/* Function declarations */
orb_node_t *orb_node_create(const struct orb_metadata_s *meta, const rt_uint8_t instance, rt_uint8_t queue_size);
rt_err_t    orb_node_delete(orb_node_t *node);
orb_node_t *orb_node_find(const struct orb_metadata_s *meta, int instance);
bool        orb_node_exists(const struct orb_metadata_s *meta, int instance);
int         orb_node_read(orb_node_t *node, void *data, rt_uint32_t *generation);
int         orb_node_write(orb_node_t *node, const void *data);
bool        orb_node_ready(orb_subscribe_t *handle);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // __UORB_NODE_H__
